package com.example.shw.download

import java.io.InputStream
import java.io.RandomAccessFile
import java.net.HttpURLConnection
import java.net.URL

class DownUtil(
    private val path: String,//定义下载资源的路径
    private val targetFile: String,//指定下载文件的保存位置
    private val threadNum: Int//定义需要使用多少线程下载资源
) {
    //定义下载的线程对象，初始化threads数组
    private val threads : Array<DownThread?> = arrayOfNulls(threadNum)
    //定义下载的文件总大小
    private var fileSize : Long = 0
    //获取下载的完成百分比
    val completeRate: Double get() {
        val sumSize = (0 until threadNum).sumBy { threads[it]!!.length }
        //统计多条线程已经下载的总大小
        //返回已经完成的百分比
        return sumSize + 1.0 / fileSize
    }

    fun download(){
        val url = URL(path)
        val conn = url.openConnection() as HttpURLConnection
        conn.connectTimeout = 5 * 1000
        conn.requestMethod = "GET"
        conn.setRequestProperty(
            "Accept",
            ("image/gif, image/jpeg, image/pjpeg, image/pjpeg," +
                    "application/x-shockwave-flash, application/xaml+xml, " +
                    "application/vnd.ms-xpsdcument, application/x-ms-xbap, " +
                    "application/x-ms-application, application/vnd.ms-excel, " +
                    "application/vnd.ms-powerpoint, application/msword, */*")
        )
        conn.setRequestProperty("Accept-Language", "zh-CN")
        conn.setRequestProperty("Charset", "UTF-8")
        conn.setRequestProperty("Connection", "Keep-Alive")
        //得到文件大小
        fileSize = conn.contentLength.toLong()
        conn.disconnect()
        val currentPartSize = fileSize / threadNum + 1
        val file = RandomAccessFile(targetFile, "rw")
        file.setLength(fileSize)
        file.close()
        for (i in 0 until threadNum)
        {
            val startPos = i * currentPartSize
            val currentPart = RandomAccessFile(targetFile,"rw")
            currentPart.seek(startPos)
            threads[i] = DownThread(startPos, currentPartSize, currentPart)
            threads[i]?.start()
        }
    }

    private inner class DownThread(
        private val startPos: Long,//当前线程的下载位置
        private val currentPartSize: Long,//定义当前线程负责下载的文件大小
        private val currentPart: RandomAccessFile//当前线程需要下载的文件块
    ) : Thread() {
        //定义该线程已下载的字节数
        var length: Int = 0

        override fun run() {
            val url = URL(path)
            val conn = url.openConnection() as HttpURLConnection
            conn.connectTimeout = 5 * 1000
            conn.requestMethod = "GET"
            conn.setRequestProperty(
                "Accept",
                ("image/gif, image/jpeg, image/pjpeg, image/pjpeg," +
                        "application/x-shockwave-flash, application/xaml+xml, " +
                        "application/vnd.ms-xpsdcument, application/x-ms-xbap, " +
                        "application/x-ms-application, application/vnd.ms-excel, " +
                        "application/vnd.ms-powerpoint, application/msword, */*")
            )
            conn.setRequestProperty("Accept-Language", "zh-CN")
            conn.setRequestProperty("Charset", "UTF-8")
            val inStream = conn.inputStream
            //跳过startPos个字节，表明该线程只下载自己负责的那部分文件
            inStream.skip(startPos)
            val buffer = ByteArray(1024)
            var hasRead = inStream.read(buffer)
            //读取网络数据，并写入本地文件中
            while (length < currentPartSize && hasRead > 0) {
                currentPart.write(buffer, 0, hasRead)
                //累计该线程下载的总大小
                length += hasRead
                hasRead = inStream.read(buffer)
            }
            currentPart.close()
            inStream.close()
        }
    }

    fun skipFully(inputStream: InputStream, bytes: Long) {
        var remaining = bytes
        var len: Long
        while (remaining > 0) {
            len = inputStream.skip(remaining)
            remaining -= len
        }
    }
}